#ifndef astartest
#define astartest

const int MapWidth=30;		//size of our map in tiles
const int MapHeight=29;
const int XOffset=5;		//where to draw the map on the screen
const int YOffset=5;
const int BlockSize=16;		//size of each tile in pixels
const int StartMenu=XOffset+(MapWidth*BlockSize)+5;		//quick calculation for drawing our menu

enum MapTypes{MAP_WALL=1,MAP_HEDGE=2};					//tile types in our map

//actions that can be performed in our little program
enum Actions{NONE,SETSTART,SETEND,SETHEDGE,SETWALL,SETNONE,CLEARALL,
				MAZE,RANDOM1,RANDOM5,RANDOM10,
				LEFT,RIGHT,UP,DOWN,ASTAR1,ASTAR2};

//all the lovely functions
bool InitialiseData();				//setup our data
bool MazeLogic();						//program loop
bool MazeDraw();						//draw the map and the menu
void CleanUp();						//free memory, etc.
void ProcessKeys();					//perform an action on the key pressed
void ClearGameMap(Actions A);		//setup our tile map (clear, draw a maze, etc)
void GenerateMaze();				//if doing a maze, this is the one that generates it
void ReInitialiseStarMap();			//redo the astar map - needed whenever the tile map is modified
void GenerateAStar(bool ad=true);	//produce an A* route to get from start to end
									//ad is allowdiagonal movement, defaults to yes
void DrawAstarRoute();				//draw the route the A* code found
void MessageBox(char* message);		//quick message on the screen

/**********************************************************************/

//everything below here is for the option to create a maze
//absolutely nothing to do with the AStar, just here to make the tool more interesting
//maze includes
#include <vector>
#include <list>
#include <string>
using namespace std;


//------------------------------------------------------------------------------
// Name: struct MazeSquare
// Desc: Representation of a single square in the maze
//------------------------------------------------------------------------------
struct MazeSquare
{
	MazeSquare() : x( 0 ), y( 0 ) {}
	MazeSquare( const int newX, const int newY ) : x( newX ), y( newY ) {}

	int x, y;
};

//------------------------------------------------------------------------------
// Name: class Grid
// Desc: The actual maze
//------------------------------------------------------------------------------
class Grid
{

public:
	enum Direction { DIR_UP, DIR_RIGHT, DIR_DOWN, DIR_LEFT };

	Grid(int w, int h, int* map);

	int GetTile( const int x, const int y ) const { return *(m_tiles+(y*mapw+x)); }
	void SetTile( const int x, const int y, int value )
	{
		*(m_tiles+(y*mapw+x)) = value;
	}

	int GetStartY() { return m_startY; }
	int GetGoalY() { return m_goalY; }

	void GenerateMaze();
private:
	int* m_tiles;

	int m_startY;
	int m_goalY;
	int mapw;
	int maph;

	list< MazeSquare > m_solution;

	bool CanPlacePath( const int x, const int y );
	void MoveInDirection( int& x, int& y, const Direction d );
};

#endif
